/**
* Set before run: -Xms512m -Xmx512m 
*/

import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

public class MemoryUsageOfCollections {
	static long lastFreeMemory = Runtime.getRuntime().freeMemory();
	static int NUMBER = 1000_000;

	public static void main(String[] args) {

		System.out.println("Array int");
		int i1[] = new int[NUMBER];
		fillArray(i1);
		checkMemory();

		System.out.println("Array Integer");
		Integer i2[] = new Integer[NUMBER];
		fillArrayInteger(i2);
		checkMemory();

		System.out.println("ArrayList");
		List<Integer> arrayList = new ArrayList<Integer>();
		fillList(arrayList);
		checkMemory();

		System.out.println("LinkedList");
		List<Integer> linkedList = new LinkedList<Integer>();
		fillList(linkedList);
		checkMemory();

		System.out.println("HashMap");
		Map<Integer, Integer> map1 = new HashMap<>();
		fillMap(map1);
		checkMemory();

		System.out.println("TreeMap");
		Map<Integer, Integer> map2 = new TreeMap<>();
		fillMap(map2);
		checkMemory();

		System.out.println("MyHash");
		MyHash mh = new MyHash();
		fillMyHash(mh);
		checkMemory();
	}

	private static void fillMyHash(MyHash m) {
		for (int j = 0; j < NUMBER; j++) {
			m.put(j, j);
		}
	}

	private static void checkMemory() {
		long free = Runtime.getRuntime().freeMemory();
		System.out.println("Free:" + free + " Total:"
				+ Runtime.getRuntime().totalMemory() + " Change:"
				+ (lastFreeMemory - free) + " PerElement:"
				+ ((lastFreeMemory - free) / NUMBER));
		lastFreeMemory = free;
	}

	private static void fillArray(int[] i) {
		for (int j = 0; j < i.length; j++) {
			i[j] = j;
		}
	}

	private static void fillArrayInteger(Integer[] i) {
		for (int j = 0; j < i.length; j++) {
			i[j] = j;
		}
	}

	private static void fillList(List<Integer> l) {
		for (int j = 0; j < NUMBER; j++) {
			l.add(j);
		}
	}

	private static void fillMap(Map<Integer, Integer> m) {
		for (int j = 0; j < NUMBER; j++) {
			Integer k = new Integer(j);
			m.put(k, k);
		}
	}

}
